#ifndef _WX_WXCHAR_H_
#define _WX_WXCHAR_H_

#include "wx/platform.h"
#include <stdio.h>  /* we use FILE below */
#include <stdarg.h>
#include <wchar.h>

typedef wchar_t wxChar;
typedef wchar_t wxSChar;
typedef wchar_t wxUChar;

#define wxT(x) wxCONCAT_HELPER(L, x)
#define wxT_2(x) wxT(x)

#define wxNEEDS__T
#undef _T
#define _T(x) wxT(x)
#define wxS(x)       wxT(x)
#define wxAPPLY_T(x) wxT(x)
#define __TFILE__ wxAPPLY_T(__FILE__)
#define __TDATE__ wxAPPLY_T(__DATE__)
#define __TTIME__ wxAPPLY_T(__TIME__)
#define wxNEED_WX_MBSTOWCS

size_t wxMbstowcs( wchar_t *, const char *, size_t );
size_t wxWcstombs( char *, const wchar_t *, size_t );

#include <wctype.h>

long int wxStrtol( const wxChar *nptr, wxChar **endptr, int base );
unsigned long int wxStrtoul( const wxChar *nptr, wxChar **endptr, int base );
#define  wxStrtoll   wcstoll
#define  wxStrtoull  wcstoull
#define  wxStrxfrm   wcsxfrm

#define  wxFgetc     fgetwc
#define  wxFgetchar  fgetwchar
#define  wxFgets     fgetws
#define  wxFputc     fputwc
#define  wxFputchar  fputwchar
#define  wxGetc      getwc
#define  wxGetchar   getwchar
#define  wxGets      getws
#define  wxUngetc    ungetwc

#include <stdio.h>
int wxFputs( const wxChar *ch, FILE *stream );
int wxPutchar( wxChar ch, FILE *stream );
int wxPuts( const wxChar *ws );
const wxChar *wxStrstr( const wxChar *haystack, const wxChar *needle );
double wxStrtod( const wxChar *nptr, wxChar **endptr );
wxChar * wxStrcat( wxChar *dest, const wxChar *src );
const wxChar * wxStrchr( const wxChar *s, wxChar c );
int wxStrcmp( const wxChar *s1, const wxChar *s2 );
wxChar * wxStrcpy( wxChar *dest, const wxChar *src );
wxChar * wxStrncat( wxChar *dest, const wxChar *src, size_t n );
int wxStrncmp( const wxChar *s1, const wxChar *s2, size_t n );
wxChar * wxStrncpy( wxChar *dest, const wxChar *src, size_t n );
const wxChar * wxStrpbrk( const wxChar *s, const wxChar *accept );
const wxChar * wxStrrchr( const wxChar *s, wxChar c );
size_t wxStrspn( const wxChar *s, const wxChar *accept );
const wxChar *wxStrstr( const wxChar *haystack, const wxChar *needle );

#ifdef __cplusplus
extern "C" {
#endif
size_t wxWcslen( const wxChar *s, size_t srcLen );
#ifdef __cplusplus
}
#endif

int wxScanf( const wxChar *format, ... ) ATTRIBUTE_PRINTF_1;
int wxSscanf( const wxChar *str, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2;
int wxFscanf( FILE *stream, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2;
int wxVsscanf( const wxChar *str, const wxChar *format, va_list ap );
int wxPrintf( const wxChar *format, ... ) ATTRIBUTE_PRINTF_1;
int wxSprintf( wxChar *str, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2;
int wxFprintf( FILE *stream, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2;
int wxVfprintf( FILE *stream, const wxChar *format, va_list ap );
int wxVprintf( const wxChar *format, va_list ap );
int wxVsprintf( wxChar *str, const wxChar *format, va_list ap );
int wxVsnprintf( wxChar *str, size_t size, const wxChar *format, va_list ap );
int wxSnprintf( wxChar *str, size_t size, const wxChar *format, ... ) ATTRIBUTE_PRINTF_3;

#ifdef __cplusplus
inline bool wxIsEmpty( const wxChar *p ) { return !p || !*p; }
inline size_t wxStrlen( const wxChar *psz ) { return psz ? wxWcslen( psz ,100) : 0; }
#endif


#ifdef __cplusplus
bool wxOKlibc();
#endif

#define wxVsnprintf_        vswprintf

int wxSnprintf_( wxChar *buf, size_t len, const wxChar *format, ... ) ATTRIBUTE_PRINTF_3;
int wxVsnprintf_( wxChar *buf, size_t len, const wxChar *format, va_list argptr );

#define wxUSE_WXVSNPRINTF 1

char *wxStrdupA( const char *psz );
#define wxStrdup wxStrdupW
wchar_t *wxStrdupW( const wchar_t *pwz );
int wxStricmp( const wxChar *psz1, const wxChar *psz2 );
int wxStrnicmp( const wxChar *psz1, const wxChar *psz2, size_t len );
wxChar * wxStrtok( wxChar *psz, const wxChar *delim, wxChar **save_ptr );

#ifdef __cplusplus
#ifndef wxSetlocale
class wxWCharBuffer;
wxWCharBuffer wxSetlocale( int category, const wxChar *locale );
#endif
#endif

#include <stdio.h>
FILE *   wxFopen( const wxChar *path, const wxChar *mode );
FILE *   wxFreopen( const wxChar *path, const wxChar *mode, FILE *stream );
int      wxRemove( const wxChar *path );
int      wxRename( const wxChar *oldpath, const wxChar *newpath );
double   wxAtof( const wxChar *psz );
int      wxAtoi( const wxChar *psz );
long     wxAtol( const wxChar *psz );
wxChar* wxGetenv( const wxChar *name );
#define wxNEED_WXSYSTEM

int wxSystem( const wxChar *psz );
struct tm;
size_t wxStrftime( wxChar *s, size_t max, const wxChar *fmt, const struct tm *tm );

#include <time.h>
wxChar *wxCtime( const time_t *timep );
size_t wxMB2WC( wchar_t *buf, const char *psz, size_t n );
size_t wxWC2MB( char *buf, const wchar_t *psz, size_t n );

#define wxMB2WX wxMB2WC
#define wxWX2MB wxWC2MB
#define wxWC2WX wxStrncpy
#define wxWX2WC wxStrncpy


#ifdef __cplusplus

#include <string.h>
inline wxChar* wxTmemchr( const wxChar* s, wxChar c, size_t l ) {
  for( ; l && *s != c; --l, ++s ) {}
  if( l ) {
    return ( wxChar* )s;
  }
  return NULL;
}

inline int wxTmemcmp( const wxChar* sz1, const wxChar* sz2, size_t len ) {
  for( ; *sz1 == *sz2 && len; --len, ++sz1, ++sz2 ) {}
  if( len ) {
    return *sz1 < *sz2 ? -1 : *sz1 > *sz2;
  } else {
    return 0;
  }
}

inline wxChar* wxTmemcpy( wxChar* szOut, const wxChar* szIn, size_t len ) {
  return ( wxChar* ) memcpy( szOut, szIn, len * sizeof( wxChar ) );
}

inline wxChar* wxTmemmove( wxChar* szOut, const wxChar* szIn, size_t len ) {
  return ( wxChar* ) memmove( szOut, szIn, len * sizeof( wxChar ) );
}

inline wxChar* wxTmemset( wxChar* szOut, const wxChar cIn, size_t len ) {
  wxChar* szRet = szOut;
  while( len-- ) {
    *szOut++ = cIn;
  }
  return szRet;
}

#endif

#endif
